package com.livepan.main.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.livepan.main.controller.viewobject.ProblemInfoVO;
import com.livepan.main.controller.viewobject.ProblemVO;
import com.livepan.server.BaseController;
import com.livepan.server.error.BusinessException;
import com.livepan.server.response.CommonReturnType;
import com.livepan.server.service.ProblemService;
import com.livepan.server.service.SubmissionService;
import com.livepan.server.service.model.ProblemModel;
import com.livepan.server.service.model.ProblemSummaryModel;
import com.livepan.server.utils.ConstUtil;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@RestController("problem")
@RequestMapping(value = "/problem")
public class ProblemController extends BaseController {
    @Autowired
    private ProblemService problemService;

    @Autowired
    private SubmissionService submissionService;


    @RequestMapping(value = "/getById")
    @ResponseBody
    public CommonReturnType getProblemById(@RequestParam("problemId") int problemId,
                                           @RequestParam("contestId") int contestId) throws BusinessException {

        //确保登录用户才能看到题目
        getUserModelFromSession();

        ProblemModel problemModel = problemService.getProblemByID(problemId);
        return CommonReturnType.create(convertProblemVOFromProblemModel(problemModel));
    }

    @RequestMapping(value = "/list")
    @ResponseBody
    public CommonReturnType listQuestion(@RequestParam(value = "keyword", required = false) String keyword,
                                         @RequestParam(value = "page", defaultValue = "1") Integer page) throws BusinessException {
        Long time1 = System.currentTimeMillis();

        int count = problemService.queryProblemCount(keyword, -1);
        //选取合适的值
        int limit = ConstUtil.problemLimit;
        int offset = (page - 1) * limit;
        List<ProblemModel> problemModelList = problemService.listProblem(keyword, offset, limit, null);
        List<ProblemInfoVO> problemInfoVOList = problemModelList.stream()
                .map(this::convertProblemInfoVOFromProblemModel).collect(Collectors.toList());


        //登录了就计算
        Long time2 = System.currentTimeMillis();
        System.out.println("time2-time1:" + (time2 - time1));
        if (getUserModelFromSession() != null) {
            Set<Integer> acceptedList = submissionService.getSubmitProblemIDList(getUserModelFromSession().getId(), 2);
            Set<Integer> allList = submissionService.getSubmitProblemIDList(getUserModelFromSession().getId(), null);
            for (ProblemInfoVO problemInfoVO : problemInfoVOList) {
                if (acceptedList.contains(problemInfoVO.getProblemId())) {
                    problemInfoVO.setStatus(Short.parseShort("1"));//通过
                } else if (allList.contains(problemInfoVO.getProblemId())) {
                    problemInfoVO.setStatus(Short.parseShort("2"));//未通过
                } else {
                    problemInfoVO.setStatus(Short.parseShort("0"));//未尝试
                }
            }
        }
        Long time3 = System.currentTimeMillis();
        System.out.println("time3-time2:" + (time3 - time2));

        Map<String, Object> result = new HashMap<>();
        result.put("totalCount", count);
        result.put("data", problemInfoVOList);
        return CommonReturnType.create(result);
    }

    private ProblemVO convertProblemVOFromProblemModel(ProblemModel problemModel) {
        if (problemModel == null) {
            return null;
        }
        ProblemVO problemVO = new ProblemVO();
        BeanUtils.copyProperties(problemModel, problemVO);
        return problemVO;
    }

    private ProblemInfoVO convertProblemInfoVOFromProblemModel(ProblemModel problemModel) {
        if (problemModel == null) {
            return null;
        }
        ProblemInfoVO problemInfoVO = new ProblemInfoVO();
        BeanUtils.copyProperties(problemModel, problemInfoVO);
        return problemInfoVO;
    }

    //todo
    @RequestMapping(value = "/summary")
    @ResponseBody
    public CommonReturnType getProblemSummary(@RequestParam("problemId") Integer problemId,
                                              @RequestParam(value = "language", required = false) Short language,
                                              @RequestParam(value = "page", defaultValue = "1") Integer page) {
        ProblemSummaryModel problemSummaryModel = new ProblemSummaryModel();


        problemSummaryModel.setUserAccept(0);
        problemSummaryModel.setTotalSubmission(0);
        problemSummaryModel.setStatistic(new ArrayList<>());
        problemSummaryModel.setSummaryList(new ArrayList());
        problemSummaryModel.setUserSubmit(10);

        return CommonReturnType.create(problemSummaryModel);
    }

    @RequestMapping("/createAndUpdate")
    @ResponseBody
    public CommonReturnType createAndUpdateProblem(@RequestBody ProblemModel problemModel
    ) throws BusinessException {
        ProblemModel newProblemModel;
        if (problemService.getProblemByID(problemModel.getProblemId()) == null) {
            newProblemModel = problemService.createProblem(problemModel);
        } else {
            newProblemModel = problemService.updateProblem(problemModel);
        }

        return CommonReturnType.create(convertProblemVOFromProblemModel(newProblemModel));
    }

    /**
     * 通过章节，得到对应的题目
     *
     * @param category 章节：1-1
     * @return
     * @throws IOException
     */
    @RequestMapping("getListByCategory")
    @ResponseBody
    public CommonReturnType getProblemListByCategory(@RequestParam("category") String category) throws IOException, BusinessException {
        List<Integer> problemIdList = parseJson(category);
        List<ProblemModel> problemModelList = new ArrayList<>();
        for (Integer integer : problemIdList) {
            problemModelList.add(problemService.getProblemByID(integer));
        }
        List<ProblemInfoVO> problemInfoVOList = problemModelList.stream()
                .map(this::convertProblemInfoVOFromProblemModel).collect(Collectors.toList());


        //登录了就计算
        System.out.println("2:" + System.currentTimeMillis());
        if (getUserModelFromSession()!=null) {
            Set<Integer> acceptedList = submissionService.getSubmitProblemIDList(getUserModelFromSession().getId(), 2);
            Set<Integer> allList = submissionService.getSubmitProblemIDList(getUserModelFromSession().getId(), null);
            for (ProblemInfoVO problemInfoVO : problemInfoVOList) {
                if (acceptedList.contains(problemInfoVO.getProblemId())) {
                    problemInfoVO.setStatus(Short.parseShort("1"));//通过
                } else if (allList.contains(problemInfoVO.getProblemId())) {
                    problemInfoVO.setStatus(Short.parseShort("2"));//未通过
                } else {
                    problemInfoVO.setStatus(Short.parseShort("0"));//未尝试
                }
            }
        }
        System.out.println("3:" + System.currentTimeMillis());

        return CommonReturnType.create(problemInfoVOList);
    }

    private List<Integer> parseJson(String category) throws IOException {
        File jsonFile = ResourceUtils.getFile("classpath:static/category.json");
        String json = FileUtils.readFileToString(jsonFile);
        JSONObject jsonObject = JSON.parseObject(json);
        return (List<Integer>) jsonObject.get(category);
    }


}
